#include "bg_decal.h"
#include "bg_scene.h"

#include "num/rand.h"
#include "script/scripthelper.h"
#include "script/write_lua.h"
#include "graphics/graphics.h"

#include "util/timer.h"				// log
#include "util/log.h"				// log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"		    

#include <cassert>
#include <algorithm>
#include <math.h>
using namespace background;
using namespace script;


BGDecal::BGDecal(BGScene*	pScene) : 
	BGElement(pScene),
	m_Additive(false),
	m_Alpha(1),
	m_InitialAlpha(1),
	m_InitialAdditive(false)
{
	m_Timer = num::RAND32::Instance().RandFloat(0, 10);
	m_Type = ELEMENT_DECAL;
}
BGDecal::~BGDecal()
{
}


void	BGDecal::FlushImages() 
{
	m_Sprite.FlushImage();
}

void	BGDecal::OnElementReset()
{
	m_Additive = m_InitialAdditive;
	m_Alpha = m_InitialAlpha;
}

bool	BGDecal::MatchSubStr(const std::string& SubStr)
{ 
	if (m_SpriteImg.find(SubStr) != std::string::npos ) return true;
		return false;
//return strstr(m_SpriteImg.c_str(), SubStr.c_str()) != NULL; 
};

void	BGDecal::Render(const math::Vec2& Offset, float Scale) 
{
	m_Sprite.Setup(GetScreenPos(Offset, Scale), m_Size*Scale, m_Rotation);
	m_Sprite.m_Additive = m_Additive;
	m_Sprite.m_Color = ColorfRGBA(1, 1, 1, m_Alpha);
	m_Sprite.RenderRotated();
}
void	BGDecal::Tick(float dt)
{
	m_Sprite.Tick(dt);
	//m_Sprite.m_Additive = m_Additive;
	//ColorSetAf(m_Sprite.m_Color, m_Alpha);
	BGElement::Tick(dt);
}

void	BGDecal::SetSprite(const std::string& Sprite)
{
	m_SpriteImg = Sprite;
	m_Sprite.Create(Sprite);
	m_Sprite.GetScreenSize(m_Size);
	m_Sprite.m_Additive = m_Additive;
	RecalcBoundingBox();
}

void	BGDecal::Load(LuaPlus::LuaObject& Obj)
{
	m_SpriteImg = ScriptHelper::GetTableString(Obj, "SpriteImg");
	m_Additive	= ScriptHelper::GetTableBool(Obj, "Additive", false);
	m_Alpha		= ScriptHelper::GetTableFloat(Obj, "Alpha", 1);
	SetSprite(m_SpriteImg);
	BGElement::Load(Obj);	// overwrite the size!

	m_InitialAlpha = m_Alpha;
	m_InitialAdditive = m_Additive;
}

void	BGDecal::Save(script::WriteLua* pWL)
{
	BGElement::Save(pWL);
	pWL->WritePair("SpriteImg", m_SpriteImg);
	pWL->WritePair("Additive", m_Additive);
	pWL->WritePair("Alpha", m_Alpha);
}


/////////////////////////
// bob decal
void	BGBobDecal::Render(const math::Vec2& Offset, float Scale) 
{
	const float	 BOB_SPEED = 1;
	const float	 BOB_MUL = 0.1f;
	float		x = sinf(m_Timer * BOB_SPEED) * m_Dir.x * BOB_MUL;
	float		y = sinf(m_Timer * BOB_SPEED) * m_Dir.y * BOB_MUL;
	math::Vec2	Bob(x*Scale, y*Scale);
	math::Vec2	P = GetScreenPos(Offset, Scale);
	m_Sprite.Setup(P+Bob, m_Size*Scale, m_Rotation);
	m_Sprite.m_Color = ColorfRGBA(1, 1, 1, m_Alpha);
	m_Sprite.RenderRotated();
}

/////////////////////////
// UV decals
void	BGUVDecal::Render(const math::Vec2& Offset, float Scale) 
{
	const float	 UV_SPEED = 2.0f;
	math::Vec2	UVOffset = m_Dir * UV_SPEED * m_Timer;

	// replace UVs
	m_Sprite.m_UV1 = m_Sprite.m_UV1 + UVOffset;
	m_Sprite.m_UV2 = m_Sprite.m_UV2 + UVOffset;

	// render
	BGDecal::Render(Offset, Scale);

	// restore
	m_Sprite.m_UV1 = m_Sprite.m_UV1 - UVOffset;
	m_Sprite.m_UV2 = m_Sprite.m_UV2 - UVOffset;

}
/////////////////////////
// Glow decals
void	BGGlowDecal::Render(const math::Vec2& Offset, float Scale) 
{
	const	float		DURATION = 3.14f * 0.5f;	// every second
	m_Alpha = 0.75f +( sinf(m_Timer * DURATION) * 0.25f);
	m_Sprite.Setup(GetScreenPos(Offset, Scale), m_Size*Scale, m_Rotation);
	m_Sprite.m_Color = ColorfRGBA(1, 1, 1, m_Alpha);
	m_Sprite.m_Additive = true;
	m_Sprite.RenderRotated();


}
